package com.sites.cms.column;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.jfinal.aop.Inject;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.ehcache.CacheKit;
import com.sites.cms.article.ArticleService;
import com.sites.common.SiteInfo;
import com.sites.common.model.Account;
import com.sites.common.model.Column;

/**
 * 栏目服务层
 * 
 * @author zyg
 * 2020年2月3日 上午11:39:49
 */
public class ColumnService {

	private Column dao = new Column().dao();
	@Inject
	private ArticleService artSrv;
	
	/**
	 * 查询一级栏目，新增栏目时作为父栏目供选择
	 * @return
	 */
	public List<Column> getParentColumns(){
		String sql = dao.getSql("column.getParentColumns");
		return dao.findByCache(SiteInfo.columnsCacheName, "parentColumns", sql, SiteInfo.siteId);
	}
	
	/**
	 * 保存栏目
	 * @param column
	 * @return
	 */
	public Ret save(Column column){
		Ret ret = Ret.create();
		String enName = column.getEnName();
		Column temp = getByEnName(enName);
		if(temp != null){
			ret.setFail();
			ret.set(SiteInfo.msgKey, "栏目英文名不可重复！");
			return ret;
		}
		column.setCreateTime(new Date());
		column.setSiteId(SiteInfo.siteId);
		column.save();//先保存，保存后才能获取id
		
		int parent = column.getParent();
		if(parent > 0){//有父节点，需要更新父节点的子栏目
			addParentColumn(column);
		}
		ret.setOk();
		ret.set(SiteInfo.msgKey, "保存成功");
		CacheKit.removeAll(SiteInfo.columnsCacheName);//新增栏目后清理掉栏目相关缓存
		return ret;
	}
	
	/**
	 * 根据栏目标识名查询栏目信息
	 * @param enName
	 * @return
	 */
	public Column getByEnName(String enName){
		String sql = dao.getSql("column.getByEnName");
		return dao.findFirst(sql, enName, SiteInfo.siteId);
	}
	
	/**
	 * 新增父栏目
	 * <br/>新增栏目时如果有选择父栏目，被选中的父栏目需要更新下子栏目一列
	 * @param column	新增的栏目
	 */
	public void addParentColumn(Column column){
		int parent = column.getParent();
		if(parent > 0){
			Column parentColumn = getById(parent);
			String children = parentColumn.getChildren();
			if(StrKit.isBlank(children)){
				children = column.getId().toString();
			} else {
				children = children + "|" + column.getId();
			}
			parentColumn.setChildren(children);
			parentColumn.update();
		}
	}
	
	/**
	 * 修改父栏目
	 * <br/>栏目修改时改动了父栏目，需要对应的修改原来和新的父栏目的子栏目一列
	 * @param columnId	修改的栏目id
	 * @param oldParent	原来的父栏目id
	 */
	public void updateParentColumn(int columnId, int oldParent){
		if(oldParent > 0){
			Column parentColumn = getById(oldParent);
			String children = parentColumn.getChildren();
			String[] childrenArray = children.split("\\|");//需要进行转译
			String newChildren = "";
			String columnIdString = String.valueOf(columnId);
			for(int i=0,j=childrenArray.length; i<j; i++){
				if(!columnIdString.equals(childrenArray[i])){
					newChildren = newChildren + "|" + childrenArray[i];
				}
			}
			//进行必要的判断，排除唯一的子栏目修改父栏目导致的报错问题
			if(StrKit.notBlank(newChildren) && newChildren.length()>1){
				newChildren = newChildren.substring(1);//去掉最开始的|
			}
			
			parentColumn.setChildren(newChildren);
			parentColumn.update();
		}
		
	}
	
	/**
	 * 查询站点所有栏目信息
	 * @return
	 */
	public List<Column> getAllColumns(){
		String sql = dao.getSql("column.getAllColumns");
		List<Column> columns = dao.find(sql, SiteInfo.siteId);
		//添加父栏目和子栏目的名字
		for(Column column : columns){
			if(column.getParent() > 0){
				column.put("parentName", getById(column.getParent()).getName());
			}
			if(StrKit.notBlank(column.getChildren())){
				column.put("childrenNames", getChildrenNames(column.getChildren()));
			}
			
		}
		return columns;
	}
	
	/**
	 * 获取所有的一级节点栏目，栏目编辑的时候需要使用
	 * @return
	 */
	public List<Column> getAllParentColumns(){
		String sql = dao.getSql("column.getAllParentColumns");
		return dao.find(sql, SiteInfo.siteId);
	}
	
	/**
	 * 获取栏目的tree结构串
	 * @return
	 */
	public String getAllColumns4tree(){
		String sql = dao.getSql("column.getAllParentColumns");
		List<Column> parentColumns = dao.find(sql, SiteInfo.siteId);
		String treeStr = formatCols4Tree(parentColumns);
		return treeStr;
	}
	
	/**
	 * 根据父栏目迭代子栏目
	 * @param columns
	 * @return
	 */
	public String formatCols4Tree(List<Column> columns){
		ArrayList<Record> recordList = new ArrayList<Record>();
		String getAllChildrenColumns = dao.getSql("column.getAllChildrenColumns");
		for(Column column : columns){
			Record record = new Record();
			record.set("id", column.getId());
			record.set("title", "'"+column.getName()+"'");
			List<Column> childrenColumns = dao.find(getAllChildrenColumns, column.getId(), SiteInfo.siteId);
			String childrenStr = "";
			if(childrenColumns.size()>0){
				childrenStr = formatCols4Tree(childrenColumns);
			}
			if(StrKit.notBlank(childrenStr)){
				record.set("children", childrenStr);
			}
			recordList.add(record);
		}
		return recordList.toString();
	}
	
	/**
	 * 根据子栏目id获取子栏目名称
	 * @param childrenIds 子栏目id字符串，如"3|4|5"
	 * @return
	 */
	public String getChildrenNames(String childrenIds){
		String childrenNames = "";
		if(StrKit.notBlank(childrenIds)){
			String[] idStrings = childrenIds.split("\\|");//需要进行转译
			String name = "";
			for(int i=0,j=idStrings.length; i<j; i++){
				name = getById(Integer.parseInt(idStrings[i])).getName();
				childrenNames = childrenNames + "|" + name;
			}
			childrenNames = childrenNames.substring(1);
		}
		return childrenNames;
	}
	
	/**
	 * 根据ID获取栏目信息
	 * @param id
	 * @return
	 */
	public Column getById(int id){
		return dao.findById(id);
	}
	
	/**
	 * 更新栏目信息
	 * @param column
	 * @return
	 */
	public Ret updateColumn(Column column){
		Ret ret = Ret.create();
		
		//查询数据库中保存的记录
		Column temp = getById(column.getId());
		//更新名字
		temp.setName(column.getName());
		/*
		 * 更新父栏目
		 * 父栏目更新比较特殊，所以做个判断以减少不必要的操作
		 */
		int tempParent = temp.getParent();
		int newParent = column.getParent();
		String children = temp.getChildren();
		if(tempParent==0 && newParent>0 && StrKit.notBlank(children)){
			ret.setFail();
			ret.set(SiteInfo.msgKey, "更新失败！<br>拥有子栏目的一级栏目不能降为二级栏目！");
			return ret;
		}
		if(temp.getParent() != column.getParent()){
			//下面三条更新语句有严格的先后顺序，不能颠倒了
			updateParentColumn(temp.getId(), temp.getParent());
			temp.setParent(column.getParent());
			addParentColumn(temp);
		}
		//更新排序
		temp.setOrder(column.getOrder());
		
		temp.setUpdateTime(new Date());
		temp.update();
		
		ret.setOk();
		ret.set(SiteInfo.msgKey, "更新成功！");
		CacheKit.removeAll(SiteInfo.columnsCacheName);//更新栏目后清理掉栏目相关缓存
		return ret;
	}
	
	/**
	 * 查询新增文章时用的栏目(做好栏目分组)
	 * @return
	 */
	public Map<String, List<Column>> getArtColumns(){
		Map<String, List<Column>> artColumnMap = new LinkedHashMap<String, List<Column>>();
		List<Column> parentColumns = getParentColumns();
		List<Column> childrenColumns;
		List<Column> othersColumns = new ArrayList<Column>();
		for(Column column : parentColumns){
			childrenColumns = getChildrenColumns(column.getId());
			if(childrenColumns.isEmpty()){//没有子栏目属于一级栏目
				othersColumns.add(column);
			} else {
				artColumnMap.put(column.getName(), childrenColumns);
			}
		}
		artColumnMap.put("一级栏目", othersColumns);
		return artColumnMap;
	}
	
	/**
	 * 根据父栏目获取子栏目列表
	 * @param parentId
	 * @return
	 */
	public List<Column> getChildrenColumns(int parentId){
		String sql = dao.getSql("column.getChildrenColumns");
		return dao.findByCache(SiteInfo.columnsCacheName, parentId, sql, parentId, SiteInfo.siteId);
	}
	
	public Ret delColumn(int id, Account account){
		//当前栏目置为删除
		Column column = getById(id);
		column.setStatus(SiteInfo.statusDel);
		column.update();
		//子栏目删除
		String delColumnSql = dao.getSql("column.delColumnSql");
		Db.update(delColumnSql, SiteInfo.statusDel, id, SiteInfo.siteId);
		//文章删除
		artSrv.delArtByCol(id, account);
		Ret ret = Ret.ok();
		ret.set(SiteInfo.msgKey, "删除成功！");
		CacheKit.removeAll(SiteInfo.columnsCacheName);//删除栏目后清理掉栏目相关缓存
		return ret;
	}
	
	public Ret activateCol(int id){
		//暂定只激活当前栏目，子栏目和文章暂不处理
		Column column = getById(id);
		column.setStatus(SiteInfo.statusNormal);
		column.update();
		Ret ret = Ret.ok();
		ret.set(SiteInfo.msgKey, "启用成功！");
		CacheKit.removeAll(SiteInfo.columnsCacheName);//激活栏目后清理掉栏目相关缓存
		return ret;
	}

	/**
	 * 删除站点的栏目信息
	 *
	 * @param siteId
	 * @return
	 */
	public Ret delSiteColumn(int siteId){
		Ret ret = Ret.ok();
		String sql = dao.getSql("column.delSiteColumn");
		Db.delete(sql, siteId);
		return ret;
	}
}
